package com.zhangxu.microservice.auth.biz.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zhangxu.microservice.auth.biz.dto.CreateRoleDTO;
import com.zhangxu.microservice.auth.biz.dto.RoleDTO;
import com.zhangxu.microservice.auth.biz.dto.UpdateRoleDTO;
import com.zhangxu.microservice.auth.biz.mapstruct.RoleConverter;
import com.zhangxu.microservice.auth.biz.service.RoleService;
import com.zhangxu.microservice.auth.common.enums.RoleStatusEnum;
import com.zhangxu.microservice.auth.dao.condition.RoleCondition;
import com.zhangxu.microservice.auth.dao.entity.RoleDO;
import com.zhangxu.microservice.auth.dao.service.RoleDao;
import com.zhangxu.microservice.common.context.EmployeeContextHolder;
import com.zhangxu.microservice.common.exception.BizException;
import com.zhangxu.microservice.common.utils.AssertUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 角色服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RoleServiceImpl implements RoleService {

    private final RoleDao roleDao;
    private final RoleConverter roleConverter;

    @Override
    public Long createRole(CreateRoleDTO createRoleDTO) {
        // 检查角色编码是否已存在
        RoleDO existingRole = roleDao.getByCode(createRoleDTO.getCode());
        if (existingRole != null) {
            throw new BizException("角色编码已存在");
        }

        // 转换并保存角色
        RoleDO roleDO = roleConverter.toRoleDO(createRoleDTO);
        roleDO.setDeleteTime(0L);
        roleDO.setStatus(RoleStatusEnum.INIT);
        roleDO.setCreateBy(EmployeeContextHolder.get().getId());
        roleDao.save(roleDO);
        return roleDO.getId();
    }

    @Override
    public void updateRole(UpdateRoleDTO updateRoleDTO) {
        // 检查角色是否存在
        RoleDO existingRole = roleDao.getById(updateRoleDTO.getId());
        AssertUtils.notNull(existingRole, "角色不存在");
        AssertUtils.isTrue(RoleStatusEnum.INIT.equals(existingRole.getStatus()), "当前状态不能编辑");

        // 转换并更新角色
        RoleDO roleDO = roleConverter.toRoleDO(updateRoleDTO);
        roleDO.setUpdateBy(EmployeeContextHolder.get().getId());
        roleDao.updateById(roleDO);
    }

    @Override
    public void deleteRole(Long roleId) {
        // 检查角色是否存在
        RoleDO existingRole = roleDao.getById(roleId);
        AssertUtils.notNull(existingRole, "角色不存在");
        AssertUtils.isTrue(RoleStatusEnum.INIT.equals(existingRole.getStatus()), "当前状态不能删除");
        // 逻辑删除角色
        RoleDO roleDO = new RoleDO();
        roleDO.setId(roleId);
        roleDO.setDeleteTime(System.currentTimeMillis());
        roleDO.setUpdateBy(EmployeeContextHolder.get().getId());
        roleDao.updateById(roleDO);
    }

    @Override
    public void enableRole(Long roleId) {
        // 检查角色是否存在
        RoleDO existingRole = roleDao.getById(roleId);
        AssertUtils.notNull(existingRole, "角色不存在");
        AssertUtils.isFalse(RoleStatusEnum.ENABLE.equals(existingRole.getStatus()), "当前状态不能启用");

        // 启用角色
        RoleDO roleDO = new RoleDO();
        roleDO.setId(roleId);
        roleDO.setStatus(RoleStatusEnum.ENABLE);
        roleDO.setUpdateBy(EmployeeContextHolder.get().getId());
        roleDao.updateById(roleDO);
    }

    @Override
    public void disableRole(Long roleId) {
        // 检查角色是否存在
        RoleDO existingRole = roleDao.getById(roleId);
        AssertUtils.notNull(existingRole, "角色不存在");
        AssertUtils.isTrue(RoleStatusEnum.ENABLE.equals(existingRole.getStatus()), "当前状态不能停用");

        // 禁用角色
        RoleDO roleDO = new RoleDO();
        roleDO.setId(roleId);
        roleDO.setStatus(RoleStatusEnum.DISABLE);
        roleDO.setUpdateBy(EmployeeContextHolder.get().getId());
        roleDao.updateById(roleDO);
    }

    @Override
    public RoleDTO getRoleById(Long roleId) {
        RoleDO roleDO = roleDao.getById(roleId);
        return roleDO != null ? roleConverter.toRoleDTO(roleDO) : null;
    }

    @Override
    public RoleDTO getRoleByCode(String code) {
        RoleDO roleDO = roleDao.getByCode(code);
        return roleDO != null ? roleConverter.toRoleDTO(roleDO) : null;
    }

    @Override
    public IPage<RoleDTO> rolePage(RoleCondition condition) {
        IPage<RoleDO> page = roleDao.page(condition);
        return page.convert(roleConverter::toRoleDTO);
    }
}